Skip to content

TIGER-291: Tiger_Secret — provider-neutral secrets / key-store (public core module) - #337

Merged
WebTigers merged 2 commits into
mainfrom
feat/tiger-291-tiger-secret
Oct 11, 2026
Merged

WebTigers merged 2 commits into
mainfrom
feat/tiger-291-tiger-secret

Conversation

@WebTigers

Copy link
Copy Markdown
Owner

What

A public core feature module that resolves secrets and sensitive config values through a config-selected backend — so where a secret lives is a configuration choice and the calling code never cares. Same pattern as Tiger_Location / Tiger_Mail / the auth credential provider: AWS SSM is an adapter, never the interface.

Parallel to Tiger_Message / modules/message: the facade + adapters live in library/Tiger/Secret/, the module (modules/secret) is the documented home + Bootstrap wiring + docs.

The contract

A secret reference is scheme:path (ssm:/tiger/prod/node/crypto_key, env:OPENSRS_KEY, file:/run/secrets/x, enc:<blob>). Tiger_Secret::resolve($value) fetches a recognized reference and passes anything else through as plaintext — the one-line swap at every existing *_enc call site.

Why it's not AWS-specific

  • Default driver is local = today's behavior (an inline Tiger_Crypto value). A shared-hosting install with tiger.secret.driver unset is unaffected and needs no cloud SDK — the layer is invisible.
  • On the fleet, driver=ssm authenticates with the EC2 instance IAM role (default AWS chain), so nothing is baked into a golden image and nothing rides in user-data.
  • This also breaks the bootstrap chicken-and-egg: tiger.crypto.key can come from SSM because SSM trusts the role, not the key. Root of trust becomes the instance role + KMS, not a pre-shared secret.

Adapters

Scheme Backend Dep
enc / local (default) inline Tiger_Crypto none
env environment variable none
file mounted secret file (Docker/k8s/systemd) none
chain try N in order none
ssm AWS SSM Parameter Store AWS SDK (tiger-sdk-aws), capability-gated
secretsmanager AWS Secrets Manager AWS SDK, capability-gated

Cloud adapters reference Aws\…\…Client only behind class_exists (or an injected client), so core vendors no AWS SDK and they're dormant/null-resolving without it — same posture as Hosting_Lib_Provisioner_Tigerden. A Tiger_Secret_Writer_Interface (put/delete) supports ops/provisioning tooling (never the request path).

Robustness

  • The facade self-wires lazily from tiger.secret.*, so it's correct in web / CLI / tests and never depends on the module being active; the Bootstrap only eager-wires for schemes() visibility + early error surfacing.
  • Fail-soft everywhere: available() is capability-detection; get() returns null for missing/unavailable; the facade guards every call. A missing SDK is a null, never a 500. Secrets are never logged.

Tests

52 unit tests (facade + every adapter; cloud adapters via a stubbed client — no SDK, no network). Full unit suite green: 1083 tests, 17,830 assertions. CAPABILITIES.md regenerated.

Consumers (separate tickets, blocked on this)

  • TIGER-292 — TigerServer: firstboot fetches bootstrap secrets from the store; stop baking blowfish_secret.
  • TIGER-293 — TigerHosting: ssm: refs on the three _enc points; drop the baked AWS provisioner key.
  • TIGER-289 — the OpenSRS relay reads its creds from the store via its role.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ

WebTigers and others added 2 commits October 11, 2026 10:51
…GER-291)

A public core feature module that resolves secrets through a config-selected
backend, so WHERE a secret lives is a config choice and the caller never cares —
the same pattern as Tiger_Location / Tiger_Mail / the auth credential provider.
AWS SSM is an adapter, never the interface.

- library/Tiger/Secret.php — the facade: resolve() (scheme ref -> fetch; else
  plaintext passthrough — the one-line swap at every *_enc call site), get(),
  register(), put(); lazy self-wiring from tiger.secret.* so it is correct with
  no Bootstrap (web/CLI/tests) and never depends on module activation.
- Adapters: Local (Tiger_Crypto enc:, the default), Env, File, Chain — all
  dependency-free, in core; Ssm + SecretsManager capability-gated on the AWS SDK
  (shipped by tiger-sdk-aws, never vendored) with an injectable client, dormant
  and null-resolving without it. Writer interface (put/delete) for ops tooling.
- modules/secret — manifest + Bootstrap (eager-wires configured backends) +
  AGENTS.md + docs/en.
- Default driver is `local` = today's behavior, so shared-hosting installs are
  unaffected and need no SDK. On the fleet, driver=ssm authenticates with the
  EC2 instance role (nothing baked, nothing in user-data) — which also breaks the
  bootstrap chicken-and-egg: crypto.key can come from SSM because SSM trusts the
  role, not the key.
- 52 unit tests (facade + every adapter; cloud via a stubbed client); full unit
  suite green (1083). CAPABILITIES.md regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ
@WebTigers
WebTigers merged commit 9cabc33 into main Oct 11, 2026
14 checks passed
@WebTigers
WebTigers deleted the feat/tiger-291-tiger-secret branch October 11, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant